package org.lep.leetcode.gasstation;

/**
 * Source : https://oj.leetcode.com/problems/gas-station/
 *
 * Created by lverpeng on 2017/8/30.
 *
 * There are N gas stations along a circular route, where the amount of gas at station i is gas[i].
 *
 * You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to
 * its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
 *
 * Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
 *
 * Note:
 * The solution is guaranteed to be unique.
 */
public class GasStation {

    /**
     *
     * 判断车能否从某一个station开始绕所有的station走一圈
     *
     * sum(gas[i]-cost[i]) < 0表示一定不能走完，否则一定可以
     *
     * 如果能绕一圈，那么怎么寻找起点
     *
     * 性质1：如果从i出发可以绕一圈，那么从i出发可以达到任意station，显而易见
     * 性质2：如果这样的i是唯一的，那么不存在 j!= i，从j出发能达到i，证明：使用反证法：假设这样的j存在，那么j能到达i，
     *      由性质1得i可以到达任意station，那么i也可以到达j，那么就可以从j出发到达j，也就是说同时存在i、j可以绕一圈，与唯一解矛盾，所以不存在
     * 性质3：假如i是唯一的解，那么从0至i-1出发无法到达i，从i出发可以到达i+1至n-1
     *
     * 结合以上三条性质，解法如下：
     * 0：如果sum(gas[i]-cost[i]) < 0表示无解，否则有解，进入1
     * 1：从0开始计算sum(gas[i]-cost[i])，如果sum < 0，则由0作为起点不能到达i,根据性质1，0不能作为起点，因为从0出发可以到达i，
     *      由性质2，1至i-1不能作为起点，那么i+1作为新的候选起始点
     * 3：以此类推，直到遇到k，从k出发能到达n-1，那么k就能绕一圈，因为这个时候k能到达n-1，加上sum(gas[i]-cost[i]) > 0一定有解的话，k就是起点
     *
     * @param gas
     * @param cost
     * @return
     */
    public int canCOmpleteCircuit (int[] gas, int[] cost) {
        int start = 0;
        int sum = 0;  // 从0开始的所有gas[i] - cost[i]和
        int sumK = 0;   // 从k开始的所有gas[i] - cost[i]和
        for (int i = 0; i < gas.length; i++) {
            sum += gas[i] - cost[i];
            sumK += gas[i] - cost[i];
            if (sumK < 0) {
                start = i+1;
                sumK = 0;
            }
        }
        if (sum < 0) {
            return -1;
        }
        return start;
    }
}
